/*
 ============================================================================
 Page	     : 483-485
 Name        : func_ptr.c
 Date	     : 20210407
 Author      : Hbue 18060333
 Copyright   : Your copyright notice
 Description : 使用指针函数
 ============================================================================
 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define LEN 81
char *s_gets(char *st, int n);
char showmenu(void);
void eatline(void);				// 读取至行末尾
void show(void(*fp)(char *), char * str);
void ToUpper(char *);				// 把字符串转换为大写
void ToLower(char *);				// 把字符串转换为小写
void Transpose(char *);				// 大小写转置
void Dummy(char *);				// 不更改字符串

int main(void)
{
	char line[LEN];
	char copy[LEN];
	char choice;
	void(*pfun)(char *);// 声明一个指针函数,被指向的函数接受char*类型的参数,无返回值、

	puts("Enter a string (empty line to quit):");
	while(s_gets(line, LEN) != NULL && line[0] != '\0')
	{
		while((choice = showmenu()) != 'n')
		{
			switch(choice)		// switch语句设置指针
			{
				case 'u':
					pfun = ToUpper;
				break;
				case 'l':
					pfun = ToLower;
				break;
				case 't':
					pfun = Transpose;
				break;
				case 'o':
					pfun = Dummy;
				break;
			}
			strcpy(copy, line);			// 为show()函数拷贝一份
			show(pfun, copy);			// 根据用户的选择,使用选定的函数
		}
		puts("Enter a string (empty line to quit):");
	}
	puts("Bye!");

	return 0;
}

char showmenu(void)
{
	char ans = 0;
	puts("Enter menu choice:");
	puts("1) uppercase       2) lowercase");
	puts("3) transposed case 4) original case");
	puts("n) next string");
	ans = getchar();		// 获得用户的输入
	ans = tolower(ans);		// 转换为小写
	eatline();				// 清理输入行
	while(strchr("ulton", ans) == NULL)
	{
		puts("Please enter a u, l, t, o, or n:");
		ans = tolower(getchar());
		eatline();
	}

	return ans;
}

void eatline(void)
{
	while(getchar() != '\n')
	{
		continue;
	}
}

void show(void(*fp)(char *), char * string)
{
	(*fp)(string);		// 把用户选定的函数作用于string
	puts(string);		// 显示结果
}

void ToUpper(char *string)
{
	while(*string)
	{
		*string = toupper(*string);
		string++;
	}
}

void ToLower(char *string)
{
	while(*string)
	{
		*string = tolower(*string);
		string++;
	}
}

void Transpose(char *string)
{
	while(*string)
	{
		if(islower(*string))
		{
			*string = toupper(*string);
		}
		else if(isupper(*string))
		{
			*string = tolower(*string);
		}
		string++;
	}
}

void Dummy(char *string)
{
	// 不改变字符串
}

char *s_gets(char *st, int n)
{
	char *ret_val = NULL;
	char *find = NULL;

	ret_val = fgets(st, n, stdin);
	if(ret_val)
	{
		find = strchr(st, '\n');	// 查找换行符
		if(find)					// 如果地址不是NULL,
		{
			*find = '\0';			// 在此处放置一个空字符
		}
		else
		{
			while(getchar() != '\n')
			{
				continue;			// 处理输入行中剩余的字符
			}
		}
	}

	return ret_val;
}

